package com.atom.module.mvvm.base.view.fragment

import android.content.Context
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import com.atom.module.mvvm.base.ApiView
import com.atom.module.mvvm.base.ApiViewModel

abstract class AbstractMVVMFragment<V : ViewDataBinding, VM : ApiViewModel> : AbstractFragment(),
    ApiView<VM> {
    protected lateinit var binding: V
    protected lateinit var viewModel: VM
    protected var contentView: View? = null

    abstract fun initContentView(
        inflater: LayoutInflater?,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): Int

    protected open fun initData(view: View) {}

    protected open fun initArgs(savedInstanceState: Bundle?) {}

    override fun onAttach(context: Context) {
        super.onAttach(context)
        initArgs(arguments)
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        if (contentView == null) {
            contentView = initMVVM(inflater, container, savedInstanceState)
        } else {
            val parent = contentView!!.parent
            if (parent != null && parent is ViewGroup) {
                parent.removeView(contentView)
            }
        }
        initData(
            contentView ?: throw RuntimeException("onCreateView error because contentView is null")
        )
        return contentView
    }

    protected fun initMVVM(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        this.binding = DataBindingUtil.inflate(
            inflater,
            initContentView(inflater, container, savedInstanceState),
            container,
            false
        )
        this.binding.lifecycleOwner = this
        this.viewModel = initViewModel().also {
            binding.setVariable(initVariableId(), it)
            lifecycle.addObserver(it)
        }
        initViewBinding(this.binding, this.viewModel)
        return this.binding.root
    }

    protected open fun initViewBinding(binding: V, viewModel: VM) {}
}
